/**
 * 全局错误处理配置
 * 统一处理各种错误情况
 */

import { constants } from '../api'

/**
 * 错误类型枚举
 */
export const ERROR_TYPES = {
  NETWORK: 'NETWORK',
  API: 'API',
  VALIDATION: 'VALIDATION',
  PERMISSION: 'PERMISSION',
  UNKNOWN: 'UNKNOWN'
}

/**
 * 错误处理器类
 */
export class ErrorHandler {
  constructor() {
    this.errorHandlers = new Map()
    this.setupDefaultHandlers()
  }

  /**
   * 设置默认错误处理器
   */
  setupDefaultHandlers() {
    // 网络错误
    this.register(ERROR_TYPES.NETWORK, (error) => {
      uni.showToast({
        title: '网络连接失败，请检查网络设置',
        icon: 'none',
        duration: 2000
      })
    })

    // API错误
    this.register(ERROR_TYPES.API, (error) => {
      const message = error.message || '服务器错误，请稍后重试'
      uni.showToast({
        title: message,
        icon: 'none',
        duration: 2000
      })
    })

    // 验证错误
    this.register(ERROR_TYPES.VALIDATION, (error) => {
      uni.showToast({
        title: error.message || '输入信息有误，请检查后重试',
        icon: 'none',
        duration: 2000
      })
    })

    // 权限错误
    this.register(ERROR_TYPES.PERMISSION, (error) => {
      uni.showToast({
        title: '权限不足，请联系管理员',
        icon: 'none',
        duration: 2000
      })
    })

    // 未知错误
    this.register(ERROR_TYPES.UNKNOWN, (error) => {
      uni.showToast({
        title: '发生未知错误，请稍后重试',
        icon: 'none',
        duration: 2000
      })
    })
  }

  /**
   * 注册错误处理器
   * @param {string} type - 错误类型
   * @param {Function} handler - 处理函数
   */
  register(type, handler) {
    this.errorHandlers.set(type, handler)
  }

  /**
   * 处理错误
   * @param {Error|Object} error - 错误对象
   * @param {string} type - 错误类型
   */
  handle(error, type = ERROR_TYPES.UNKNOWN) {
    console.error(`[${type}] Error:`, error)
    
    const handler = this.errorHandlers.get(type)
    if (handler) {
      handler(error)
    } else {
      // 使用默认处理器
      const defaultHandler = this.errorHandlers.get(ERROR_TYPES.UNKNOWN)
      if (defaultHandler) {
        defaultHandler(error)
      }
    }
  }

  /**
   * 根据错误信息自动判断错误类型并处理
   * @param {Error|Object} error - 错误对象
   */
  autoHandle(error) {
    let type = ERROR_TYPES.UNKNOWN

    if (error.name === 'NetworkError' || error.message?.includes('network')) {
      type = ERROR_TYPES.NETWORK
    } else if (error.code) {
      // 根据API错误码判断
      switch (error.code) {
        case '400':
          type = ERROR_TYPES.VALIDATION
          break
        case '401':
        case '403':
          type = ERROR_TYPES.PERMISSION
          break
        case '500':
        case '5000':
          type = ERROR_TYPES.API
          break
        default:
          type = ERROR_TYPES.API
      }
    }

    this.handle(error, type)
  }
}

// 创建全局错误处理器实例
export const globalErrorHandler = new ErrorHandler()

/**
 * 表单验证错误处理
 */
export const validateForm = (form, rules) => {
  const errors = []

  for (const field in rules) {
    const rule = rules[field]
    const value = form[field]

    // 必填验证
    if (rule.required && (!value || (typeof value === 'string' && !value.trim()))) {
      errors.push({
        field,
        message: rule.message || `${rule.label || field}不能为空`
      })
      continue
    }

    // 长度验证
    if (value && rule.minLength && value.length < rule.minLength) {
      errors.push({
        field,
        message: `${rule.label || field}长度不能少于${rule.minLength}个字符`
      })
    }

    if (value && rule.maxLength && value.length > rule.maxLength) {
      errors.push({
        field,
        message: `${rule.label || field}长度不能超过${rule.maxLength}个字符`
      })
    }

    // 数值验证
    if (value && rule.min && Number(value) < rule.min) {
      errors.push({
        field,
        message: `${rule.label || field}不能小于${rule.min}`
      })
    }

    if (value && rule.max && Number(value) > rule.max) {
      errors.push({
        field,
        message: `${rule.label || field}不能大于${rule.max}`
      })
    }

    // 正则验证
    if (value && rule.pattern && !rule.pattern.test(value)) {
      errors.push({
        field,
        message: rule.message || `${rule.label || field}格式不正确`
      })
    }

    // 自定义验证
    if (value && rule.validator) {
      const result = rule.validator(value, form)
      if (result !== true) {
        errors.push({
          field,
          message: result || `${rule.label || field}验证失败`
        })
      }
    }
  }

  return errors
}

/**
 * 显示表单验证错误
 */
export const showValidationErrors = (errors) => {
  if (errors.length > 0) {
    globalErrorHandler.handle(
      { message: errors[0].message },
      ERROR_TYPES.VALIDATION
    )
    return false
  }
  return true
}

/**
 * 常用验证规则
 */
export const commonRules = {
  required: (label) => ({
    required: true,
    label,
    message: `${label}不能为空`
  }),

  phone: (label = '手机号') => ({
    pattern: /^1[3-9]\d{9}$/,
    label,
    message: '请输入正确的手机号码'
  }),

  email: (label = '邮箱') => ({
    pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
    label,
    message: '请输入正确的邮箱地址'
  }),

  password: (label = '密码') => ({
    minLength: 6,
    maxLength: 20,
    label,
    message: '密码长度应为6-20个字符'
  }),

  number: (label, min, max) => ({
    pattern: /^\d+$/,
    min,
    max,
    label,
    message: `请输入正确的${label}`
  }),

  budget: (label = '预算') => ({
    validator: (value, form) => {
      const num = Number(value)
      if (isNaN(num) || num <= 0) {
        return '请输入正确的金额'
      }
      return true
    },
    label
  })
}

/**
 * 业务错误处理
 */
export const businessErrorHandler = {
  // 订单相关错误
  orderNotFound: () => {
    uni.showToast({
      title: '订单不存在或已被删除',
      icon: 'none'
    })
  },

  orderStatusError: () => {
    uni.showToast({
      title: '订单状态异常，请刷新后重试',
      icon: 'none'
    })
  },

  // 教师相关错误
  teacherNotFound: () => {
    uni.showToast({
      title: '教师信息不存在',
      icon: 'none'
    })
  },

  teacherNotVerified: () => {
    uni.showToast({
      title: '该教师尚未通过认证',
      icon: 'none'
    })
  },

  // 支付相关错误
  paymentFailed: () => {
    uni.showToast({
      title: '支付失败，请重试',
      icon: 'none'
    })
  },

  insufficientBalance: () => {
    uni.showToast({
      title: '余额不足，请先充值',
      icon: 'none'
    })
  }
}

export default globalErrorHandler
